﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GodPl;
using GodPl.GameObjects;
using GodPl.GameObjects.Creatures;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace GodPl.WorldState
{
    public class World
    {
        GodPlGame game;
        Texture2D background;
        Rectangle backgroundRectangle;
        List<GameObject> gameObjects;

        /// <summary>
        /// Holds a queue of objects to be added on the next update
        /// </summary>
        Queue<GameObject> queuedObjects;
        Weather weather;

        List<Briyya> briyyas;

        public List<Briyya> Briyyas
        {
            get { return briyyas; }
        }

        int briyyaCounter;

        public int NextBriyyaId()
        {
            briyyaCounter++;
            return briyyaCounter;
        }

        public ContentManager Content
        {
            get { return game.Content; }
        }

        public Weather Weather
        {
            get { return weather; }
        }

        public List<GameObject> GameObjects
        {
            get { return gameObjects; }
        }

        public World (GodPlGame game)
        {
            this.game = game;
            background = game.Content.Load<Texture2D>("grass-1024x768");
            backgroundRectangle = new Rectangle(0, 0, GodPlGame.ScreenWidth, GodPlGame.ScreenHeight);

            weather = new Weather(this);
            gameObjects = new List<GameObject>();
            briyyas = new List<Briyya>();

        }

        /// <summary>
        /// List of preset layouts for the world. This can eventually be replaced with layouts that get loaded in
        /// from an XML or CSV file.
        /// </summary>
        public enum WorldLayout
        {
            Default
        }

        public void Populate(WorldLayout layout)
        {
            switch (layout)
            {
                case WorldLayout.Default:

                    AddObject(new Wall(this, Side.Left));
                    AddObject(new Wall(this, Side.Right));
                    AddObject(new Wall(this, Side.Top));
                    AddObject(new Wall(this, Side.Bottom));

                    var t = new AppleTree(this, GetRandomLocation());
                    AddObject(t);

                    for (int i = 0; i < 6; ++i)
                    {
                        AddRandomBoulder();
                    }

                    for (int i = 0; i < 4; ++i)
                    {
                        AddRandomAppleTree();
                    }

                    break;
            }
        }

        public Briyya AddRandomBriyya()
        {
            return AddRandomBriyya(GetRandomLocation());
        }

        public Briyya AddRandomBriyya(Vector2 position)
        {
            Genes genes = new Genes(null, Genes.RandomSex(), true);
            Briyya b = new Briyya(this, position, genes);
            while (b.IsColliding())
            {
                b.Position = GetRandomLocation();
            }

            AddObject(b);
            return b;
        }


        public Boulder AddRandomBoulder()
        {
            Boulder b = new Boulder(this, GetRandomLocation());
            while (b.IsColliding())
            {
                b.Position = GetRandomLocation();
            }
            AddObject(b);
            return b;
        }

        public AppleTree AddRandomAppleTree()
        {
            AppleTree b = new AppleTree(this, GetRandomLocation());
            while (b.IsColliding())
            {
                b.Position = GetRandomLocation();
            }
            AddObject(b);
            return b;
        }


        public Vector2 GetRandomLocation()
        {
            return new Vector2(GodPlGame.RandomGen.Next(10, GodPlGame.ScreenWidth-10), GodPlGame.RandomGen.Next(10, GodPlGame.ScreenHeight-10));
        }

        public void AddObject(GameObject obj)
        {

            gameObjects.Add(obj);
            if (obj.GetType() == typeof(Briyya))
            {
                briyyas.Add((Briyya)obj);
            }
        }

        public void Update(GameTime gameTime)
        {
            weather.Update(gameTime);

            // Can't use foreach loop because objects might be added during loop

            int num = gameObjects.Count;
            for (int i = 0; i < num; ++i)
            {
                gameObjects[i].Update(gameTime);
            }
        }

        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(background, backgroundRectangle, Color.White);

            foreach (GameObject obj in gameObjects)
            {
                obj.Draw(gameTime, spriteBatch);
            }
        }
    }
}
